<?php
/*
RPHP Model
@category  Core
 */
RPHP::loadClass("ModelTrait", LIB_PATH);
class RPHP_Model
{
    use ModelTrait;
    //mysql
    protected $_dbconfig  = '_db';
    protected $_primarydb = 'primary';
    //redis
    protected $_redisconfig  = '_cache';
    protected $_primaryredis = 'primary';
    //
    protected $_conf           = null;
    protected $c               = null;
    protected $_dbcloaded      = false;
    protected $_redisconnected = false;
    public $_dbc               = array();
    public $_prefix            = array();
    public $_shop              = null;
    public $_user              = null;
    /**
     * Error
     */
    protected $_error;

    public function __construct($c)
    {
        $this->c                          = $c;
        $this->_conf                      = RPHP::loadConfig("config/db");
        $this->_prefix[$this->_primarydb] = $this->_conf[$this->_dbconfig][$this->_primarydb]['prefix'];

    }

    public function __destruct()
    {
        if ($this->_dbc[$this->_primarydb]) {
            $this->db->close();
        }

        if ($this->_redisconnected) {
            $this->redis->close();
        }

    }

    public function redis()
    {
        if (!$this->_redisconnected) {
            $this->_redisconnected = true;
            RPHP::loadClass($this->_conf[$this->_redisconfig]['adapter'], COM_PATH . DIRECTORY_SEPARATOR . "Db");
            $class = "RPHP_Db_" . $this->_conf[$this->_redisconfig]['adapter'];
            return new $class($this->_conf[$this->_redisconfig][$this->_primaryredis]);
        }

    }

    public function db($server = null)
    {
        if (!$this->_dbcloaded) {
            $this->loadDbc();
            $this->_dbcloaded = true;
        }
        if (!$server) {
            $server = $this->_primarydb;
        }

        $class                  = "RPHP_Db_" . $this->_conf[$this->_dbconfig]['adapter'];
        $this->_dbc[$server]    = 1;
        $this->_prefix[$server] = $this->_conf[$this->_dbconfig][$server]['prefix'];
        return new $class($this->_conf[$this->_dbconfig][$server]);

    }

    public function loadDbc()
    {
        RPHP::loadClass("Abstract", COM_PATH . DIRECTORY_SEPARATOR . "Db");
        RPHP::loadClass($this->_conf[$this->_dbconfig]['adapter'], COM_PATH . DIRECTORY_SEPARATOR . "Db");
    }

    public function sql($sql)
    {
        $result = $this->db->sql($sql);
        return $result;
    }

    public function checkAuth($goto = true)
    {
        //如果有COOKIE
        if (isset($_COOKIE[$this->c['cookie']['user']]) && $_COOKIE[$this->c['cookie']['user']] != "") {
            $data = unserialize(Rfc::decode($_COOKIE[$this->c['cookie']['user']]));
            if ($data['uid']) {

                $token = md5($data['uid'] . $this->c['secrkey'] . $data['signin_time'] . $data['signin_ip']);

                if ($token == $data['token']) {
                      
                    // 检查在线信息
                    $sql       = "SELECT `id` FROM {$this->_prefix['primary']}member_online WHERE `uid`=" . $data['uid'] . " AND `token`='" . $token . "' ORDER BY `id` DESC LIMIT 1";
                    $online_id = $this->db->getone($sql);
                    if ($online_id > 0) {
                        
                        $sql       = "SELECT `level_type` FROM {$this->_prefix['primary']}member_account WHERE `uid`=" . $data['uid'] . " LIMIT 1";
                        $level_type = $this->db->getone($sql);
                        $data['level_type'] = $level_type;
                        $this->_user = $data;
                        return $data;
                    }
                }
            }
        }

        if ($goto) {
            $url = "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
            header("location: /passport/signin?url=" . Rfc::encode($url));
            exit;
        } else {
            return false;
        }
    }

    // get weixin setting
    public function getWeixinSetting($checkAccessToken = false)
    {
        $sql     = "SELECT * FROM {$this->_prefix['primary']}weixin_setting LIMIT 1";
        $setting = $this->db->getrow($sql);
        if ($setting) {

            if ($checkAccessToken) {
                // check weixin access_token
                if ($setting['expires_in'] < $_SERVER['REQUEST_TIME']) {
                    $url  = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $setting['appid'] . "&secret=" . $setting['appsecret'] . "";
                    $html = file_get_contents($url);
                    if ($html != "") {
                        $json = json_decode($html, true);
                        if ($json['access_token'] != "") {
                            $setting['access_token'] = $json['access_token'];
                            $setting['expires_in']   = $_SERVER['REQUEST_TIME'] + 6600;
                            $sql                     = "UPDATE {$this->_prefix['primary']}weixin_setting SET `access_token`='" . $setting['access_token'] . "',`expires_in`=" . $setting['expires_in'];
                            $uptoken                 = $this->sql($sql);
                        }
                    }
                }

                // check jsapi ticket

                if ($setting['jsapi_expires_in'] < $_SERVER['REQUEST_TIME']) {
                    $url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' . $setting['access_token'] . '&type=jsapi';

                    $json_data = file_get_contents($url);
                    if ($json_data != "") {

                        $json_token = json_decode($json_data, true);

                        if ($json_token['ticket'] != "") {
                            $setting['jsapi_expires_in'] = $_SERVER['REQUEST_TIME'] + 6600;
                            $setting['jsapi_ticket']     = $json_token['ticket'];

                            $sql      = "UPDATE {$this->_prefix['primary']}weixin_setting SET `jsapi_ticket`='" . $setting['jsapi_ticket'] . "',`jsapi_expires_in`=" . $setting['jsapi_expires_in'];
                            $upticket = $this->sql($sql);
                        }

                    }
                }
            }

            return $setting;
        }
    }

    //Make JSAPI
    public function getJSApiData($url = '')
    {

        $setting = $this->getWeixinSetting(true);
        if ($setting) {

            if ($setting['jsapi_ticket'] != "") {

                if ($url == '') {
                    $para['url'] = "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
                } else {
                    $para['url'] = $url;
                }

                $para['noncestr']     = substr(md5($para['url'] . $_SERVER['REQUEST_TIME'] . $_SERVER['REMOTE_ADDR'] . $_SERVER['REMOTE_PORT'] . $_SERVER['HTTP_USER_AGENT']), 0, 16);
                $para['jsapi_ticket'] = $setting['jsapi_ticket'];
                $para['timestamp']    = $_SERVER['REQUEST_TIME'];

                ksort($para);
                foreach ($para as $k => $v) {
                    $vlas[] = $k . "=" . $v;
                }

                $out['signature'] = sha1(implode("&", $vlas));
                $out['appId']     = $setting['appid'];
                $out['nonceStr']  = $para['noncestr'];
                $out['timestamp'] = $_SERVER['REQUEST_TIME'];
                $out['url']       = $para['url'];

                return $out;
            }
        }

    }

/*-extend----------------------------*/

    //function class
    public function fun()
    {
        RPHP::loadClass("Function", LIB_PATH);
        return new RPHP_Functions();
    }
    //upload class
    public function upload()
    {
        RPHP::loadClass("Upload", LIB_PATH);
        return new RPHP_Upload();
    }

/*-magic-----------*/

    public function __set($key, $value = null)
    {
        $this->$key = $value;
    }

    public function __get($key)
    {
        switch ($key) {
            case 'db':
                $this->db = $this->db();
                return $this->db;
            case 'redis':
                $this->redis = $this->redis();
                return $this->redis;
            case 'fun':
                $this->fun = $this->fun();
                return $this->fun;
            case 'upload':
                $this->upload = $this->upload();
                return $this->upload;
        }
    }

}
